package jmine.tec.scheduling.domain;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.Version;

import jmine.tec.persist.annotation.Alias;
import jmine.tec.persist.annotation.Comment;
import jmine.tec.persist.annotation.Constraint;
import jmine.tec.persist.annotation.DiscriminatorComment;
import jmine.tec.persist.annotation.UniqueConstraint;
import jmine.tec.scheduling.ScheduledJobExecutionContext;
import jmine.tec.scheduling.SchedulingController;
import bancosys.tec.component.Documentation;
import bancosys.tec.persist.authorization.annotation.DisplayName;
import bancosys.tec.persist.bussobj.PersistableBusinessObject;
import bancosys.tec.persist.persister.annotation.NaturalKey;

/**
 * @author ricardo.abe
 */
@Entity
@Alias("SCHTSK")
@Table(name = "SCHEDULED_TASK")
@DisplayName("ScheduledTask")
@Documentation("TABELA QUE CONTEM AS TAREFAS AGENDADAS")
@SequenceGenerator(name = "SEQ_SCHTSK", sequenceName = "SEQ_SCHTSK")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TP", discriminatorType = DiscriminatorType.INTEGER)
@Comment(table = "SCHEDULED_TASK", column = "TP", value = "INDICA O TIPO DE TAREFA AGENDADA.")
@DiscriminatorComment("SIMPLES")
@DiscriminatorValue("0")
@Constraint(suffix = "JT_1")
public class ScheduledTask extends PersistableBusinessObject {

    private Long id;

    private Long version;

    private String mnemonic;

    private String description;

    private Boolean active;

    private String cron;

    private String condition;

    private String action;

    /**
     * @return o id da tarefa.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_SCHTSK")
    @Documentation("CODIGO DA SCHEDULED TASK")
    @Column(name = "COD_SCHEDULED_TASK", nullable = false)
    public Long getId() {
        return this.id;
    }

    /**
     * @return the version
     */
    @Version
    @Documentation("VERSAO DO REGISTRO DA TAREFA")
    @Column(name = "VERSION", nullable = false)
    public Long getVersion() {
        return this.version;
    }

    /**
     * @return the mnemonic
     */
    @NaturalKey
    @UniqueConstraint(suffix = "JT_0")
    @Documentation("MNEMONICO DA TAREFA AGENDADA")
    @Column(name = "MNE", nullable = false)
    public String getMnemonic() {
        return this.mnemonic;
    }

    /**
     * @return the description
     */
    @Documentation("DESCRICAO DA TAREFA AGENDADA")
    @Column(name = "DESCR", nullable = false)
    public String getDescription() {
        return this.description;
    }

    /**
     * @return the active
     */
    @Constraint(suffix = "JT_0")
    @Documentation("TAREFA ATIVA OU INATIVA")
    @Column(name = "ACTIVE", nullable = false)
    public Boolean getActive() {
        return this.active;
    }

    /**
     * @return a condição de execução
     */
    @Documentation("CONDICAO DE EXECUCAO DA TAREFA")
    @Column(name = "CONDITION", nullable = false)
    public String getCondition() {
        return this.condition;
    }

    /**
     * @return the cron
     */
    @Documentation("EXPRESSAO DE HORA EM QUE A TAREFA DEVE SER EXECUTADA")
    @Column(name = "CRON", nullable = false)
    public String getCron() {
        return this.cron;
    }

    /**
     * @return the action
     */
    @Documentation("ACAO QUE DEVE SER EXECUTADA")
    @Column(name = "ACTION", nullable = false)
    public String getAction() {
        return this.action;
    }

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param version the version to set
     */
    public void setVersion(Long version) {
        this.version = version;
    }

    /**
     * @param mnemonic the mnemonic to set
     */
    public void setMnemonic(String mnemonic) {
        this.mnemonic = mnemonic;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @param active the active to set
     */
    public void setActive(Boolean active) {
        this.active = active;
    }

    /**
     * @param cron the cron to set
     */
    public void setCron(String cron) {
        this.cron = cron;
    }

    /**
     * @param condition the condition to set
     */
    public void setCondition(String condition) {
        this.condition = condition;
    }

    /**
     * @param action the action to set
     */
    public void setAction(String action) {
        this.action = action;
    }

    /**
     * Verifica se a condição para execução é satisfeita
     * 
     * @param context context
     * @return boolean
     */
    public boolean isConditionSatisfied(ScheduledJobExecutionContext context) {
        return this.getSchedulingController().findCondition(this).isSatisfied(context);
    }

    /**
     * Executa a ação
     * 
     * @param context context
     * @throws Exception if anything wrong happens
     */
    public void executeAction(ScheduledJobExecutionContext context) throws Exception {
        this.getSchedulingController().findAction(this).execute(context);
    }

    /**
     * Obtains a reference to the scheduling controller
     * 
     * @return controller
     */
    @Transient
    protected SchedulingController getSchedulingController() {
        return (SchedulingController) this.getController();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return this.mnemonic;
    }
}
